package com.navinfo.platform.trip.common.util;

import com.navinfo.platform.trip.common.arithmetic.exception.RangeAssert;

import java.math.BigDecimal;
import java.util.Map;

import static java.math.BigDecimal.ROUND_HALF_UP;

/**
 * 基础算法类集合.
 * @author 水哥
 */
public class ArithmeticUtils {

    private ArithmeticUtils() {
    }

    /**
     * 根据经纬度获取区域编码
     * @param lat           纬度
     * @param lon           经度
     * @param tileLcMapping 瓦片与区域映射表
     * @return 区域ID
     */
    public static Integer getLc(int lat, int lon, Map<Long, Integer> tileLcMapping) {
        if (tileLcMapping == null) {
            return null;
        }
        Long tileIdMin = TileUtils.getTileId(lat, lon, 15);
        return tileLcMapping.get(tileIdMin);
    }

    /**
     * 加速度算法.
     * @param preSpeedMs     上一个节点速度，单位m/s
     * @param currentSpeedMs 当前节点速度，单位m/s
     * @param millisecond    时间差，单位毫秒
     * @return Double 加速度
     */
    public static Double calcAcceleration(double preSpeedMs, double currentSpeedMs, long millisecond) {
        RangeAssert.speedIsInTheRange(preSpeedMs);
        RangeAssert.speedIsInTheRange(currentSpeedMs);
        RangeAssert.millisecondIsInTheRange(millisecond);
        BigDecimal seconds = BigDecimalUtils.divide(millisecond, 1000, 2);
        if (preSpeedMs == 0 || seconds.equals(BigDecimal.ZERO)) {
            return 0d;
        }
        return BigDecimalUtils.divide(currentSpeedMs - preSpeedMs, seconds, 2).doubleValue();
    }

    /**
     * 速度换算，千米/小时 转成 m/s.
     * @param speedKmh 速度km/h
     * @return 速度m/s
     */
    public static Double speedKmhToMs(int speedKmh) {
        RangeAssert.speedKmhIsInTheRange(speedKmh);
        return BigDecimalUtils.divide(BigDecimalUtils.multiply(speedKmh, 1000), 3600, 2).doubleValue();
    }

    /**
     * 速度换算，m/s 转成千米/小时 .
     * @param speedMs 速度m/s
     * @return 速度km/h
     */
    public static int speedMsToKmh(double speedMs) {
        return BigDecimalUtils.divide(BigDecimalUtils.multiply(speedMs, 3600, 2), 1000, 2).setScale(1, ROUND_HALF_UP).intValue();
    }

    /**
     * 油耗单位转换, 毫升转ml
     * @param ml double类型ml
     * @return int类型ml
     */
    public static int fuelMlToMl(double ml) {
        return BigDecimalUtils.multiply(ml, 1,0).intValue();
    }

    /**
     * 油耗单位转换, l转ml
     * @param l double类型l
     * @return  int类型ml
     */
    public static int fuelLToMl(double l) {
        return BigDecimalUtils.multiply(l, 1000, 0).intValue();
    }

    /**
     * 里程单位转换：double类型的米转为int类型的米
     * @param m double类型米
     * @return  int类型米
     */
    public static int mileageMToM(double m) {
        return BigDecimalUtils.multiply(m, 1.0, 0).intValue();
    }
    /**
     * 里程单位转换：double类型的千米转为int类型的米
     * @param km 千米
     * @return 米
     */
    public static int mileageKMToM(double km) {
        return BigDecimalUtils.multiply(km, 1000, 0).intValue();
    }

    /**
     * 时长单位转换,毫秒转为秒
     * @param ms 毫秒
     * @return  秒
     */
    public static int timeMsToSecond(int ms) {
        // 60*10
        return BigDecimalUtils.divide(ms, 1000, 0).intValue();
    }

    /**
     * 时长单位转换,毫秒转为秒
     * @param ms 毫秒
     * @return  秒
     */
    public static Integer timeMsToSecond(Integer ms) {
        if (ms == null) {
            return null;
        }
        // 60*10
        return BigDecimalUtils.divide(ms, 1000, 0).intValue();
    }

    /**
     * 时长单位转换：double类型的秒为int类型的秒
     * @param s double类型秒时长
     * @return  int类型秒时长
     */
    public static int timeSToS(double s) {
        return BigDecimalUtils.multiply(s, 1.0, 0).intValue();
    }

    /**
     * 时长单位转换,分钟转为毫秒
     * @param minute 分钟时长
     * @return  毫秒时长
     */
    public static int timeMinuteToMs(int minute) {
        // 60*10
        return minute * 60000;
    }

}
